/**
 *     This file is part of cesm-ws.
 *
 *     cesm-ws, Web Service for Community Earth System Model
 *
 *     Copyright (c) 2010, Purdue University and/or affilicates or thrid-party contributors as
 *     indicated by the @author tags or express copyright attribution statements
 *     applied by the authors. All third-party contributions are distributed under
 *     license by Purdue University.
 *
 *     cesm-ws is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with this distribution.  If not, see <http://www.gnu.org/licenses/>.
 */

package edu.purdue.rcac.cesm.facade;

import java.util.List;

import javax.activation.DataHandler;

import edu.purdue.rcac.cesm.Constants.EnvFile;
import edu.purdue.rcac.cesm.define.ComponentSet;
import edu.purdue.rcac.cesm.define.Resolution;
import edu.purdue.rcac.cesm.facade.bean.AllCaseInfoBean;
import edu.purdue.rcac.cesm.facade.bean.AllCaseNameBean;
import edu.purdue.rcac.cesm.facade.bean.AllJobInfoBean;
import edu.purdue.rcac.cesm.facade.bean.AllocationsBean;
import edu.purdue.rcac.cesm.facade.bean.CaseConfigFileBean;
import edu.purdue.rcac.cesm.facade.bean.CaseConfigInfoBean;
import edu.purdue.rcac.cesm.facade.bean.CaseRuntimeInfoBean;
import edu.purdue.rcac.cesm.facade.bean.ConfigVarBean;
import edu.purdue.rcac.cesm.facade.bean.ConfigVarListBean;
import edu.purdue.rcac.cesm.facade.bean.CreateCaseBean;
import edu.purdue.rcac.cesm.facade.bean.DownloadBean;
import edu.purdue.rcac.cesm.facade.bean.FileBean;
import edu.purdue.rcac.cesm.facade.bean.KeyValueEntry;
import edu.purdue.rcac.service.dispatch.ServiceDispatcherManagement.AuthDatabase;
import edu.purdue.rcac.service.dispatch.ServiceDispatcherManagement.SubmitType;
import edu.purdue.rcac.service.dispatch.ServiceDispatcherManagement.SubmitterImpLanguage;

/**
 * Local interface for stateless session bean {@link ServiceFacade}
 * 
 * @author Han Zhang
 */
public interface ServiceFacadeLocal {
	public static final String LOCAL_JNDI_BINDING = "ServiceFacade/local";

	public static final SubmitType DEFAULT_SUBMIT_TYPE = SubmitType.GLOBUS;

	public static final SubmitterImpLanguage DEFAULT_SUBMITTER_LANG = SubmitterImpLanguage.JAVA;

	// --------------- Getters & Setters ----------------
	/**
	 * Get case related information
	 * 
	 * @throws Exception
	 */
	public CaseRuntimeInfoBean getCaseRuntimeInfo(String userName,
			String caseName, String token) throws Exception;

	public CaseConfigInfoBean getCaseConfigInfo(String userName,
			String caseName, String token) throws Exception;

	/**
	 * Query the status of a case
	 */
	public String getJobStatus(String userName, String caseName, String token)
			throws Exception;

	/**
	 * Query the walltime usage
	 */
	public String getUsedWallTime(String userName, String caseName, String token)
			throws Exception;

	/**
	 * Query the CPU usage
	 */
	public String getUsedCPUTime(String userName, String caseName, String token)
			throws Exception;

	/**
	 * Return output file location for download (http/ftp?)
	 */
	public String getOutputLocation(String userName, String caseName,
			String token) throws Exception;

	/**
	 * Get the current value of a configuration variable
	 */
	public ConfigVarBean queryConfigVar(String varName, String userName,
			String caseName, String token) throws Exception;

	/**
	 * Set the value of a configuration variable
	 */
	public String setConfigVar(String varName, String varValue,
			String userName, String caseName, String token) throws Exception;

	/**
	 * Return pbs.out content
	 */
	public String getPbsOut(String username, String casename, String token)
			throws Exception;

	/**
	 * Return pbs.err content
	 */
	public String getPbsErr(String username, String casename, String token)
			throws Exception;

	// ------------ End of Getters & Setters ------------

	// --------------- Authentication -----------------
	/**
	 * Return a token if user is authenticated, otherwise return ""
	 */
	public String authenticate(String username, String password, AuthDatabase db)
			throws Exception;

	public String createUserHome(String userName, String token)
			throws Exception;

	/**
	 * Return "true" if token is valid, otherwise return "false"
	 */
	public boolean isTokenValid(String username, String token) throws Exception;

	// ----------- End of Authentication --------------

	// ----------- Stage Transition Actions ----------------
	/**
	 * Create a new test case
	 */
	public CreateCaseBean createCase(Resolution resolution,
			ComponentSet componentSet, String allocation, String machine,
			String caseName, String userName, String password, AuthDatabase db)
			throws Exception;

	/**
	 * Configure a case
	 */
	public String configureCase(String userName, String caseName, String token)
			throws Exception;

	/**
	 * Reset configuration
	 */
	public String resetConfig(String userName, String caseName, String token)
			throws Exception;

	/**
	 * Build and Run a CESM case
	 */
	public String runCase(String userName, String caseName, String email,
			String queueToRun, String wallTime, String token) throws Exception;

	/**
	 * Cancel a case which is either in queue or running
	 */
	public String cancelCase(String userName, String caseName, String token)
			throws Exception;

	/**
	 * Delete all the data related to a case from the system
	 */
	public String deleteCase(String userName, String caseName, String token)
			throws Exception;

	// ---------- End of Stage Transition Actions -----------

	/**
	 * Show all the cases owned by a user
	 */
	public AllCaseNameBean listAllCaseName(String userName, String token)
			throws Exception;

	/**
	 * List all the configuration variables that can be changed
	 */
	public ConfigVarListBean getConfigVarList(String userName, String caseName,
			String token) throws Exception;

	/**
	 * Invoke `qstat -a -u username` in the backend
	 */
	public AllJobInfoBean listAllJobInfo(String userName, String queueName,
			String machine, String token) throws Exception;

	/**
	 * List current allocations of a user
	 */
	public AllocationsBean listAllocation(String userName, String token)
			throws Exception;

	public String setConfigVarList(String userName, String caseName,
			List<KeyValueEntry> varList, String token) throws Exception;

	public AllCaseInfoBean listAllCaseInfo(String userName, String token)
			throws Exception;

	// ///////////////////////////////////////////////////////////
	// ////////////////// FILE OPERATION ////////////////////////
	// ///////////////////////////////////////////////////////////
	public String upload(String userName, String toPath, DataHandler data,
			String token) throws Exception;

	public List<FileBean> list(String userName, String path, String baseDir,
			String token) throws Exception;

	public String mkdir(String userName, String path, String baseDir,
			String token) throws Exception;

	public String remove(String userName, String path, String baseDir,
			String token) throws Exception;

	public String move(String userName, String path, String toPath,
			String baseDir, String token) throws Exception;

	public String rename(String userName, String fromPath, String toPath,
			String baseDir, String token) throws Exception;

	public DownloadBean download(String userName, String path, String token)
			throws Exception;

	// TODO: to be tested
	public String publish(String userName, String caseName, String token)
			throws Exception;

	public String unpublish(String userName, String caseName, String token)
			throws Exception;

	public String getPublishStatus(String userName, String caseName,
			String token) throws Exception;
}
